# XPath

# XPath 简介
# XPath 是一门在 XML 文档中定位元素的语言，它是一门基于 XML 树结构的语言，可以用来在 XML 文档中选取节点或者节点集合。
# XPath 语言提供了一套完整的路径表达式，用于在 XML 文档中选取节点或者节点集合。
# XPath 语言的语法简洁、易于学习、易于使用，是 XML 文档处理的重要工具。

# XPath 语言的主要用途包括：
# - 网页内容的自动提取：XPath 可以用来定位网页中的特定元素，并提取其内容。
# - 数据提取：XPath 可以用来从 XML 文档中提取特定的数据，并进行进一步的处理。
# - 数据验证：XPath 可以用来验证 XML 文档中的数据是否符合预期。
# - 数据转换：XPath 可以用来将 XML 文档中的数据转换成其他格式。
# - 网页内容的自动更新：XPath 可以用来自动更新网页内容，例如，当网页中的数据发生变化时，XPath 可以用来自动更新网页内容。

# XPath 语法
# XPath 语言的语法包括：
# - 路径表达式：XPath 路径表达式用于在 XML 文档中选取节点或者节点集合。
# - 谓语：XPath 语言支持各种谓语，用于对节点进行过滤、排序、计算等操作。
# - 轴：XPath 语言支持 9 种轴，用于在 XML 文档中定位节点。
# - 函数：XPath 语言支持丰富的函数，用于对节点集合进行处理。

# XPath 轴
# XPath 轴是 XPath 语言的重要组成部分，用于在 XML 文档中定位节点。
# 9 种 XPath 轴包括：
# - child：选取当前节点的子节点。
# - descendant：选取当前节点的所有后代节点，包括子节点、孙节点等。
# - attribute：选取当前节点的属性。
# - self：选取当前节点。
# - parent：选取当前节点的父节点。
# - ancestor：选取当前节点的所有祖先节点。
# - following-sibling：选取当前节点的下一个兄弟节点。
# - preceding-sibling：选取当前节点的上一个兄弟节点。
# - namespace：选取当前节点的命名空间。

# XPath 路径表达式
# XPath 路径表达式是 XPath 语言的核心，用于在 XML 文档中选取节点或者节点集合。
# XPath 路径表达式的语法如下：
# - 节点选取：节点选取用于选取某个节点或者节点集合。
# - 路径表达式：路径表达式用于连接节点选取，形成完整的路径。
# - 谓语：谓语用于对节点进行过滤、排序、计算等操作。
# - 轴：轴用于在 XML 文档中定位节点。
# - 变量：变量用于在 XPath 表达式中存储数据。
# - 函数：函数用于对节点集合进行处理。

# 节点选取-路径表达式
"""
表达式          描述
nodename       选取名称为 nodename 的节点的所有子节点
/              选取根节点
//             选取文档中的所有节点，包括子节点、孙节点等
.              选取当前节点
..             选取当前节点的父节点
@              选取属性
*              通配符，用于选取任何元素节点
"""


# 示例-路径表达式
'''
路径表达式       描述
bookstore      选取所有名称为 bookstore 的节点
/bookstore     选取根元素 bookstore(注释：此处的 / 用法表示从根节点开始选取)
bookstore/book 选取名称为 book 的子元素，位于名称为 bookstore 的元素之下
//book         选取所有名称为 book 的元素，包括子元素、孙元素等
bookstore//book 选取名称为 book 的元素，不管它们位于 bookstore 之下的什么位置
@lang          选取所有带有名为 lang 的属性
'''


# 谓语
# 谓语用于对节点进行过滤、排序、计算等操作。
# 谓语语法包括：
# - 路径表达式：用于指定某个节点的位置。
# - 运算符：用于对节点进行比较、计算等操作。
# - 谓语：用于连接多个谓语。
'''
路径表达式                                     描述
/bookstore/book[1]                           选取属于 bookstore 子元素的第一个 book 元素
/bookstore/book[last()]                      选取属于 bookstore 子元素的最后一个 book 元素
/bookstore/book[last()-1]                    选取属于 bookstore 子元素的倒数第二个 book 元素
/bookstore/book[position()<3]                选取属于 bookstore 子元素的前两个 book 元素
//title[@lang]                               选取所有带有 lang 属性的 title 元素
//title[@lang='eng']                         选取所有 lang 属性值为 eng 的 title 元素
/bookstore/book[price>35.00]                 选取属于 bookstore 子元素的所有 book 元素，其 price 属性的值大于 35.00
/bookstore/book[price>25.00 and price<35.00] 选取属于 bookstore 子元素的所有 book 元素，其 price 属性的值大于 25.00 小于 35.00
/bookstore/book[price>35.00]//title          选取属于 bookstore 子元素的所有 book 元素的 title 元素，且其中的 price 元素的值须大于 35.00
'''


# 通配符
# 通配符用于选取任何元素节点。
# 通配符语法包括：
# - *：用于选取任何元素节点。
# - @*：用于选取任何属性节点。
# - node():用于选取任何类型的节点。

# 示例-通配符
'''
路径表达式                    描述
/bookstore/*                选取 bookstore 元素的所有子节点
//*                         选取文档中的所有元素。
//title[@*]                 选取所有带有属性的 title 元素。
//title[@*='Italian']       选取所有带有属性值为 Italian 的 title 元素。
//node()                    选取文档中的所有节点。
'''

# 多路径表达式
# 路径表达式可以连接多个节点选取，形成多个路径。
# 多个路径之间使用 | 符号进行分隔。
# 示例-多路径表达式
'''
路径表达式                                描述
//book/title | //book/price             选取 book 元素的所有 title 和 price 元素。
//title | //price                       选取文档中的所有 title 和 price 元素。
/bookstore/book/title | //price         选取属于 bookstore 元素的 book 元素的所有 title 元素，以及文档中所有的 price 元素。
'''

# 运算符
# 运算符用于对节点进行比较、计算等操作。
# 运算符语法包括：
# - 路径表达式：用于指定某个节点的位置。
# - 运算符：用于对节点进行比较、计算等操作。
# - 谓语：用于连接多个谓语。

# 示例-运算符
'''
路径表达式                     描述
/bookstore/book[price>35.00]  选取属于 bookstore 子元素的所有 book 元素，其 price 属性的值大于 35.00
/bookstore/book[price>25.00 and price<35.00] 选取属于 bookstore 子元素的所有 book 元素，其 price 属性的值大于 25.00 小于 35.00
/bookstore/book[price>35.00]//title  选取属于 bookstore 子元素的所有 book 元素的 title 元素，且其中的 price 元素的值须大于 35.00
'''

# 函数
# 函数用于对节点集合进行处理。
# 函数语法包括：
# - 函数名称：用于指定函数的名称。
# - 函数参数：用于指定函数的参数。
# - 函数调用：用于调用函数。

# 示例-函数
'''
函数名称             描述
last()              选取最后一个节点。
position()          选取当前节点的位置。
count()             计算节点的个数。
name()              选取节点的名称。
text()              选取节点的文本内容。
concat()            连接两个或多个字符串。
starts-with()       判断字符串是否以指定字符串开头。
contains()          判断字符串是否包含指定字符串。
substring-before()  选取字符串中指定字符串之前的部分。
substring-after()   选取字符串中指定字符串之后的部分。
substring()         选取字符串中指定位置的部分。
normalize-space()   去除字符串两端的空白符。
translate()         替换字符串中的一部分字符。
'''



# 轴
# 轴用于在 XML 文档中定位节点。
# 轴语法包括：
# - 轴名称：用于指定轴的类型。
# - 轴名称后跟冒号（:）：用于指定轴的名称空间。
# - 轴名称后跟斜线（/）：用于连接轴和节点选取。
# - 轴名称后跟双斜线（//）：用于选取文档中的所有节点，包括子节点、孙节点等。

# 示例-轴
'''
轴名称          描述
ancestor                选取当前节点的所有祖先节点。
ancestor-or-self        选取当前节点的所有祖先节点，包括当前节点本身。
attribute               选取当前节点的属性。
child                   选取当前节点的子节点。
descendant              选取当前节点的所有后代节点，包括子节点、孙节点等。
descendant-or-self      选取当前节点的所有后代节点，包括当前节点本身。
following               选取文档中当前节点的结束标签之后的所有节点。
following-sibling       选取当前节点之后的所有兄弟节点
namespace               选取当前节点的所有命名空间节点。
parent                  选取当前节点的父节点。
preceding               选取文档中当前节点的开始标签之前的所有节点。
preceding-sibling       选取当前节点之前的所有兄弟节点。
self                    选取当前节点。
'''

# 示例-轴-路径表达式
'''
匹配包含了 class 属性为 el-table__body-wrapper 的 div 元素的后代元素 span 元素，且 span 元素的文本内容为 NO.1234
//div[contains(@class, 'el-table__body-wrapper')]/descendant::span[text()='NO.1234’]
'''



# 示例
# 以下是一个示例，演示了如何使用 XPath 定位节点：
# 假设有一个 XML 文档如下：
# ```xml
# <bookstore>
#   <book category="cooking">
#     <title lang="en">Everyday Italian</title>
#     <author>Giada De Laurentiis</author>
#     <year>2005</year>
#     <price>30.00</price>
#   </book>
#   <book category="children">
#     <title lang="en">Harry Potter</title>
#     <author>J.K. Rowling</author>
#     <year>2005</year>
#     <price>29.99</price>
#   </book>
# </bookstore>
# ```

# 要定位所有书名为 "Everyday Italian" 的节点，可以使用以下 XPath 表达式：
# ```xpath
# //book/title[text()='Everyday Italian']
# ```
# 该表达式使用了两个轴：
# - //：用于选取文档中的所有节点。
# - book：用于选取所有 book 节点。
# 然后，使用 child 轴选取 title 节点，并使用 text() 函数选取节点的文本内容。
# 最后，使用 = 运算符进行比较，选取 text() 等于 "Everyday Italian" 的节点。

# 要定位所有书名包含 "Harry" 的节点，可以使用以下 XPath 表达式：
# ```xpath
# //book/title[contains(text(), 'Harry')]
# ```
# 该表达式使用了 contains() 函数，该函数用于判断某个字符串是否包含另一个字符串。

# 要定位所有书的价格大于 20 美元的节点，可以使用以下 XPath 表达式：
# ```xpath
# //book[price>20]
# ```
# 该表达式使用了 price 节点选取，并使用 > 运算符进行比较，选取 price 值大于 20 的节点。

# 要定位所有书的作者是 "J.K. Rowling" 的节点，可以使用以下 XPath 表达式：
# ```xpath
# //book[author='J.K. Rowling']
# ```
# 该表达式使用了 author 节点选取，并使用 = 运算符进行比较，选取 author 值等于 "J.K. Rowling" 的节点。
